<?php

/**
 * Vega Framework
 *
 * @url http://vega.com.vn
 * @url http://clip.vn
 */

class Vega_Validation
{
	protected $_ins;
	protected $_error			= FALSE;
	protected $_rules 			= array();
	protected $_errormsg 		= array();
	protected $_mymessages   	= array();
	protected $_fmessages 		= array();
	protected $_msgtemplates 	= array(
				'required'		=> '%field% is required',
				'max_length'	=> '%field% is too long(%val% characters max)',		
				'min_length'	=> '%field% is too short(%val% characters min)',
				'equal'			=> '%field% is not equal %val%', 
				'equal_field'	=> '%field% value is not equal %val% value',
				'valid_email'	=> '%field% is not valid',
	);
	
	public function __construct($rules=null)
	{
		if ($rules && is_array($rules)) $this->_rules = $rules;
	}
	
	public function setRules($rules)
	{
		if ( ! is_array($rules))
			return;
		else
			$this->_rules = $rules;
	}
	
	public function setInstance($ins)
	{
		$this->_ins =& $ins;
		$this->_ins->validator = $this;
	}
	
	public function execute()
	{
		if (!$this->_rules) return TRUE;
		else
		{
			foreach ($this->_rules AS $field => $rules)
			{
			
				$value = isset($_POST[$field]) ? $_POST[$field] : '';
				$rules = explode('|', $rules);

				foreach ($rules AS $rule)
				{
					$rule 	= trim($rule);
					$param 	= array($value);
					
					$rule = explode(':', $rule);
					$func = $rule[0];
					if (isset($rule[1]) && $rule[1]) 
					{
						$val = $rule[1];
						$param = array($value, $val);
					}
					else $val = '';
					
					// Is the controller rule?			
					$callback= FALSE;
					if (substr($func, 0, 5) == 'call_')
					{
						$func = substr($func, 5);
						$param = array($val);
						$callback = TRUE;
					}
					
					if($callback)
					{
						if (!method_exists($this->_ins, $func))
						{
							$this->_error = TRUE;
							$this->_errormsg[$field] = 'This validator type('.$func.') not found';
							
							continue;
						}
						elseif (!call_user_method_array($func, $this->_ins, $param))
						{
							$this->_error = TRUE;
							$this->_errormsg[$field] = $this->_formatmsg($field, $func, $val);
							
							continue;		
						}
						else
						{
							//OK 
							continue;
						}
					}

					if (!method_exists($this, $func))
					{
						$this->_error = TRUE;
						$this->_errormsg[$field] = 'This validator type('.$func.') not found';
						
						continue;
					}
					elseif (!call_user_method_array($func, $this, $param))
					{
						$this->_error = TRUE;
						$this->_errormsg[$field] = $this->_formatmsg($field, $func, $val);
						
						continue;		
					}
				}

			}
			
			if ($this->_error)
				return FALSE;
			else 
				return TRUE;
		}
	}
	
	public function getErrorMessages()
	{
		return $this->_errormsg;
	}
	
	public function setErrorMessages($messages)
	{
		if (is_array($messages)) $this->_mymessages = $messages;
	}
	
	public function setMessage($func, $msg)
	{
		$this->_fmessages[$func] = $msg;
	}
	
	protected function _formatmsg($field, $func, $val)
	{
		if (isset($this->_fmessages[$func]) && $this->_fmessages[$func])
		{
			$message = $this->_fmessages[$func];
		}
		elseif (isset($this->_mymessages[$field][$func]) && $this->_mymessages[$field][$func])
		{
			$message =$this->_mymessages[$field][$func];
		}
		else
		{
			$message = $this->_msgtemplates[$func];
		}
			
		$patterns 		= array('/%field%/', '/%val%/');
		$replacements 	= array($field, $val);
		
		return preg_replace($patterns, $replacements, $message);
	}
		
	public function required($str)
	{
		if ( ! is_array($str))
		{
			return (trim($str) == '') ? FALSE : TRUE;
		}
		else
		{
			return ( ! empty($str));
		}
	}
	
	public function equal($num, $numc)
	{
		return ((int)$num == (int)$numc) ? TRUE : FALSE;
	}
	
	public function equal_field($str, $field)
	{
		if ( ! isset($_POST[$field]))
		{
			return FALSE;
		}

		return ($str !== $_POST[$field]) ? FALSE : TRUE;
	}
	
	public function equal_str($str, $strc)
	{
		return strcmp($str, $strc) ? FALSE : TRUE;
	}
	
	public function valid_email($str)
	{
		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
	}

	public function valid_emails($str)
	{
		if (strpos($str, ',') === FALSE)
		{
			return $this->valid_email(trim($str));
		}
		
		foreach(explode(',', $str) as $email)
		{
			if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
			{
				return FALSE;
			}
		}
		
		return TRUE;
	}
	
	public function valid_url($str)
	{
	    return (preg_match('/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)/i', $str)) ? TRUE : FALSE;
	}
	
	public function min_length($str, $val)
	{
		if (preg_match("/[^0-9]/", $val))
		{
			return FALSE;
		}
	
		return (strlen($str) < $val) ? FALSE : TRUE;
	}
	
	public function max_length($str, $val)
	{
		if (preg_match("/[^0-9]/", $val))
		{
			return FALSE;
		}
	
		return (strlen($str) > $val) ? FALSE : TRUE;
	}

	public function alpha($str)
	{
		return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
	}
	
	public function alpha_numeric($str)
	{
		return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
	}

	public function numeric($str)
	{
		return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);

	}

    public function is_numeric($str)
    {
        return ( ! is_numeric($str)) ? FALSE : TRUE;
    } 

	public function integer($str)
	{
		return (bool)preg_match('/^[\-+]?[0-9]+$/', $str);
	}
	
	public function greater_than($num, $val)
	{
		return ((int)$num >= (int)$val) ? TRUE : FALSE;
	}
	
	public function less_than($num, $val)
	{
		return ((int)$num <= (int)$val) ? TRUE : FALSE;
	}
}